#pragma once

#include<iostream>
#include<algorithm>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include<wchar.h>
#include<assert.h>
#include<pthread.h>
#include<semaphore.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<time.h>
#include <math.h>
#include<sys/time.h>
#include <string.h>
#include<stdlib.h>
#include <arpa/inet.h>

using namespace std;
#define CP_CHINESE_PRC 936
/*****************typedef**********************/
typedef unsigned short  USHORT;
typedef unsigned char   UCHAR;
typedef int CFile;

typedef  char                CHAR;
typedef  char              _TCHAR;
typedef  char               TCHAR;
//FIXME: This is important
/*
 * FIXME:  int  32bit ;
* ubuntu:  long 64bit  long long 64bit
* windows��Arm: long 32bit  long long 64bit
*
*/
//The long types of different platforms are unified into 32 bits

#ifdef AGV_LINUX_DEBUG
typedef    int                LONG;     //in ubuntu-64 long is 64bit
typedef    unsigned int       ULONG;    //in ubuntu-64 long is 64bit
#else
typedef    long               LONG;     //in  arm linux long is 32bit
typedef    unsigned long      ULONG;    //in  arm linux long is 32bit
#endif
//important Error:DWORD time =  GettickCount() is  unsigned long long
//arm  long = 4  longlong = 8  int = 4
typedef unsigned long       DWORD;     //pointer in linux is 64bit?, windows is 32bit  long
typedef  int                BOOL;
typedef char* 				LPCTSTR;
// typedef unsigned char       byte;
// typedef byte                BYTE;
typedef unsigned short      WORD;
typedef float               FLOAT;
typedef short               SHORT;
typedef int                 INT;
typedef unsigned int        UINT;
typedef  std::string       String;
typedef  pthread_t         CWinThread;
typedef int                SOCKET;
typedef void *             LPVOID;
typedef struct sockaddr_in        SOCKADDR_IN ;


//#define IO_NOT_EXIST 0
#define SYSTEMTIME tm
#define GetLength size
#define GetAt at
#ifdef AGV_LINUX_DEBUG
    #define ASSERT  assert
    #define VERIFY  ASSERT
#else
    #define ASSERT
    #define VERIFY
#endif //AGV_LINUX_DEBUG_TIMER


#ifndef WAIT_OBJECT_0
#define WAIT_OBJECT_0  0
#endif

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif

#ifndef __linux
 #define __linux 1
#endif

#ifndef SOCKET_ERROR
#define SOCKET_ERROR -1
#endif


#define inp(u)			0
#define outp(u, x)

#define  _stprintf  sprintf
#define  __max_      max
#define  __min_      min
#define  _tcsclen   strlen
#define  _tcslen    strlen

#define _tcscat wcscat

typedef  sem_t*            HANDLE;

typedef struct _tagBITMAPFILEHEADER {
    WORD    bfType;
    DWORD   bfSize;
    WORD    bfReserved1;
    WORD    bfReserved2;
    DWORD   bfOffBits;
} BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER {
        DWORD      biSize;
        LONG       biWidth;
        LONG       biHeight;
        WORD       biPlanes;
        WORD       biBitCount;
        DWORD      biCompression;
        DWORD      biSizeImage;
        LONG       biXPelsPerMeter;
        LONG       biYPelsPerMeter;
        DWORD      biClrUsed;
        DWORD      biClrImportant;
} BITMAPINFOHEADER;

#define VISIT_FOR_EACH_STL(iter, type, container)	\
        for(type::iterator (iter) = container.begin(); (iter) != container.end(); ++(iter))

#define VISIT_FOR_EACH_STL_CONST(iter, type, container)	\
        for(type::const_iterator (iter) = container.begin(); (iter) != container.end(); ++(iter))

#define FUNCTION_FAIL(function, ret, res)	\
        if ((ret) == (function)) {	\
        return (res);	\
        }

#define SAFE_DEL(x)	\
        if ((x)) {	\
        delete (x);	\
        (x) = NULL;	\
        }

#define SAFE_DEL_ARRAY(x)	\
        if ((x)) {	\
        delete [] (x);	\
        (x) = NULL;	\
        }

#define SAFE_REL(x)	\
        if ((x)) {			\
        (void)((x)->Release());	\
        (x) = NULL;		\
        }

#define SAFE_FREE(x)	\
        if ((x)) {			\
        free(x);	\
        (x) = NULL;		\
        }

#include<pthread.h>
class CriticalSection
{
public:
        CriticalSection() {
                pthread_mutex_init(&mutex_, nullptr);
        }

        ~CriticalSection() {
                pthread_mutex_destroy(&mutex_);
        }

public:
        BOOL Unlock() {
                return pthread_mutex_unlock(&mutex_) == 0;
        }

        BOOL Lock() {
                return pthread_mutex_lock(&mutex_) == 0;
        }
private:
        pthread_mutex_t  mutex_;

};

/*************************Set pthrea priority*******************************************/
#ifndef PTHREAD_PRIORITY
    #define THREAD_PRIORITY_LOWEST          1
    #define THREAD_PRIORITY_BELOW_NORMAL    (THREAD_PRIORITY_LOWEST+1)
    #define THREAD_PRIORITY_NORMAL          96
    #define THREAD_PRIORITY_HIGHEST         99
    #define THREAD_PRIORITY_ABOVE_NORMAL    (THREAD_PRIORITY_HIGHEST-1)
#endif
/*************************************************************************************/

#define    PARAM_1  std::placeholders::_1
#define    PARAM_2  std::placeholders::_2
#define    PARAM_3  std::placeholders::_3
#define    PARAM_4  std::placeholders::_4
#define    PARAM_5  std::placeholders::_5
#define    PARAM_6  std::placeholders::_6
#define    PARAM_7  std::placeholders::_7
#define    PARAM_8  std::placeholders::_8

